package net.novaborn.smtp.server;

import io.netty.channel.*;
import net.novaborn.comm.SpringContextHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.context.support.WebApplicationContextUtils;

import java.net.InetAddress;
import java.util.concurrent.TimeUnit;

public class SmtpServerHandler extends SimpleChannelInboundHandler<String> {
    private static String hostname = "www.novaborn.net";

    private boolean dataMode = false;

    private StringBuffer message = new StringBuffer();

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        // Send greeting for a new connection.
        channel.writeAndFlush("220 " + hostname + " ESMTP\r\n");
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, String msg) {
        Channel channel = ctx.channel();
        String line = msg;

        if (dataMode == false) {
            onCommand(channel, line);
        } else {
            onData(channel, line);
        }
    }

    private void onCommand(Channel channel, String line) {
        String command;
        String parameters;
        int i = line.indexOf(" ");
        if (i > 0) {
            command = line.substring(0, i).toUpperCase();
            parameters = line.substring(i + 1);
        } else {
            command = line.toUpperCase();
        }

        if (command.length() == 0) {
            channel.writeAndFlush("500 Error: bad syntax\r\n");
            return;
        }

        if (command.equals("HELO")) {
            channel.writeAndFlush("250 " + hostname + "\r\n");
        } else if (command.equals("EHLO")) {
            channel.writeAndFlush("250 " + hostname + "\r\n");
        } else if (command.equals("MAIL")) {
            message.setLength(0);
            channel.writeAndFlush("250 OK\r\n");
        } else if (command.equals("RCPT")) {
            channel.writeAndFlush("250 OK\r\n");
        } else if (command.equals("DATA")) {
            dataMode = true;
            channel.writeAndFlush("354 End data with <CR><LF>.<CR><LF>\r\n");
        } else if (command.equals("RSET")) {
            channel.writeAndFlush("250 OK\r\n");
        } else if (command.equals("QUIT")) {
            ChannelFuture future = channel.writeAndFlush("221 " + hostname + " closing connection\r\n");
        } else {
            channel.writeAndFlush("500 unrecognized command\r\n");
        }
    }

    private void onData(Channel channel, String line) {
        if (line.trim().equals(".")) {
            // end-of-data
            dataMode = false;
            saveData();
            channel.writeAndFlush("250 OK\r\n");
        } else {
            // unescape leading dot
            if (line.startsWith("..")) {
                line = line.substring(1);
            }
            message.append(line);
        }
    }


    private void saveData(){
        StringRedisTemplate stringRedisTemplate = SpringContextHolder.getBean(StringRedisTemplate.class);
        stringRedisTemplate.boundValueOps().set(,5, TimeUnit.MINUTES);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        Channel ch = ctx.channel();
        ch.close();
    }
}